#include "b_king.h"

#include "board.h"
#include "gameengine.h"
#include <iostream>

using namespace std;

King::King() {
}

King::King(int r, int c , Color color) {
	row = r;
	col = c;
	pColor = color;
	setImage();
}


King::~King() {

}


void King::setImage() {
	if(pColor==white) {
		image = W_KING;
	} else {
		image = B_KING;
	}
}

void King::GetAllPossible(std::vector <Cell>  & moves) {

	for(int i = -1 ; i <=1 ; i++) {
		if(MyFunctions::isInRange(row+1,col+i) && !(myBoard->hasTeamate(pColor,row+1,col+i)))
			moves.push_back(Cell(row+1,col+i));
	}
	for(int i = -1 ; i <=1 ; i++) {
		if(MyFunctions::isInRange(row-1,col+i) && !(myBoard->hasTeamate(pColor,row-1,col+i)))
			moves.push_back(Cell(row-1,col+i));
	}

	if(MyFunctions::isInRange(row,col-1) && !(myBoard->hasTeamate(pColor,row,col-1)))
		moves.push_back(Cell(row,col-1));

	if(MyFunctions::isInRange(row,col+1) && !(myBoard->hasTeamate(pColor,row,col+1)))
		moves.push_back(Cell(row,col+1));

	CheckForCastle(moves);


}

void King::CheckForCastle(std::vector <Cell> & moves) {
	if(pColor == white) {
		if(myBoard->whiteKingMoved) {
			return;
		} else {
			if(!myBoard->hasAnyPiece(7,5) && !myBoard->hasAnyPiece(7,6) &&
			        !myBoard->whiteRRookMoved) {
				moves.push_back(Cell(7,6));
				myBoard->willDoCastle = true;
			}
			if(!myBoard->hasAnyPiece(7,1) && !myBoard->hasAnyPiece(7,2) &&
			        !myBoard->hasAnyPiece(7,3) && !myBoard->whiteLRookMoved) {
				moves.push_back(Cell(7,2));
				myBoard->willDoCastle = true;

			}
		}
	} else {
		if(myBoard->blackKingMoved) {
			return;
		} else {
			if(!myBoard->hasAnyPiece(0,5) && !myBoard->hasAnyPiece(0,6) &&
			        !myBoard->blackRRookMoved) {
				moves.push_back(Cell(0,6));
				myBoard->willDoCastle = true;
			}
			if(!myBoard->hasAnyPiece(0,1) && !myBoard->hasAnyPiece(0,2) &&
			        !myBoard->hasAnyPiece(0,3) && !myBoard->blackLRookMoved) {
				moves.push_back(Cell(0,2));
				myBoard->willDoCastle = true;

			}
		}
	}
}

bool King::isPiece() {
	return true;
}


void King::setCell(int r, int c) {
	row = r;
	col = c;
}

Color King::GetColor() {
	return pColor;
}

ImageName King::GetImage() {
	return image;
}


bool King::Test(std::ostream &os) {
	bool success = true;
	if (!King::TestMoves(std::cout)) success = false;
	if (!King::TestCheck(std::cout)) success = false;
	return success;
}

bool King::TestMoves(std::ostream &os) {

	bool success = true;

	GameEngine testGame;
	testGame.gameStarted = true;
        testGame.myBoard.piecesOnBoard.push_back(new King(0,0,white));
        testGame.myBoard.piecesOnBoard.push_back(new King(3,3,white));
        testGame.myBoard.piecesOnBoard.push_back(new King(6,1,white));
        testGame.myBoard.piecesOnBoard.push_back(new King(5,6,white));

	testGame.myBoard.piecesOnBoard.push_back(new Knight(6,0,black));
	testGame.myBoard.piecesOnBoard.push_back(new Knight(7,0,black));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(7,1,black));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,1,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,2,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(7,2,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(4,5,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(4,6,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(4,7,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,5,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,2,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,7,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,5,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,6,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,7,white));

        testGame.myBoard.blackKingMoved = true;
        testGame.myBoard.whiteKingMoved = true;

	testGame.turn = white;
        ChessPiece * p1 = testGame.myBoard.piecesOnBoard[1-1];
        ChessPiece * p2 = testGame.myBoard.piecesOnBoard[2-1];
        ChessPiece * p3 = testGame.myBoard.piecesOnBoard[3-1];
        ChessPiece * p4 = testGame.myBoard.piecesOnBoard[4-1];

        p1->setBoard(&testGame.myBoard);
        p2->setBoard(&testGame.myBoard);
        p3->setBoard(&testGame.myBoard);
        p4->setBoard(&testGame.myBoard);

        std::vector<Cell> moves1;
        std::vector<Cell> moves2;
        std::vector<Cell> moves3;
        std::vector<Cell> moves4;

        p1->GetAllPossible(moves1);
        p2->GetAllPossible(moves2);
        p3->GetAllPossible(moves3);
        p4->GetAllPossible(moves4);

        std::vector<Cell>answer1;
        std::vector<Cell>answer2;
        std::vector<Cell>answer3;
        std::vector<Cell>answer4;

	answer1.push_back(Cell(1,0));
	answer1.push_back(Cell(0,1));
	answer1.push_back(Cell(1,1));

        answer2.push_back(Cell(2,2));
        answer2.push_back(Cell(2,3));
        answer2.push_back(Cell(2,4));
        answer2.push_back(Cell(3,2));
        answer2.push_back(Cell(3,4));
        answer2.push_back(Cell(4,2));
        answer2.push_back(Cell(4,3));
        answer2.push_back(Cell(4,4));

        answer3.push_back(Cell(5,0));
        answer3.push_back(Cell(6,0));
        answer3.push_back(Cell(7,0));
        answer3.push_back(Cell(7,1));



        TEST(Pawn::CheckCellVectors(moves1,answer1));
        TEST(Pawn::CheckCellVectors(moves2,answer2));
        TEST(Pawn::CheckCellVectors(moves3,answer3));
        TEST(Pawn::CheckCellVectors(moves4,answer4));



	return success;
}

bool King::TestCheck(std::ostream &os) {

	bool success = true;
	GameEngine testGame;
	testGame.gameStarted = true;
	testGame.turn = white;

	/*
	0 1 2 3 4 5 6 7
	  0 . . . . . . . .
	  1 . . . . . . . .
	  2 . . . . . . . .
	  3 . . . . . . . .
	  4 K . . . . . . .
	  5 . . Q P . . . . TEST 1 | TEST 2
	  6 . . . k . . . .
	  7 . . . . . . . .
	  */

	testGame.myBoard.piecesOnBoard.push_back(new King(6,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,3,black));
	testGame.myBoard.piecesOnBoard.push_back(new King(4,0,black));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(5,2,black));

	ChessPiece * p1 = testGame.myBoard.piecesOnBoard[0];


        testGame.myBoard.blackKingMoved = true;
        testGame.myBoard.whiteKingMoved = true;


	std::vector<ChessPiece *>::iterator it;
	for ( it = testGame.myBoard.piecesOnBoard.begin() ;
	        it < testGame.myBoard.piecesOnBoard.end() ; it++) {
		ChessPiece * p = *it;
		p->setBoard(&testGame.myBoard);
	}

	std::vector<Cell> moves1;

	testGame.FindMoves(moves1,p1);

	std::vector<Cell> answer1;

	answer1.push_back(Cell(5,4));
	answer1.push_back(Cell(5,2));
	answer1.push_back(Cell(7,3));

	TEST(Pawn::CheckCellVectors(moves1,answer1));

	return success;
}

int King::getValue()
{
    return 15;
}


/*
  TEST MOVES------------------------

  Capital = black
  lower = white
  p = pawn
  Q = queen
  k = king
  h = Knight

    0 1 2 3 4 5 6 7
  0 k . . . . . . .
  1 . . . . . . . .
  2 . . . . . . . .
  3 . . . k . . . .
  4 . . . . . p p p
  5 . p p . . p k p
  6 H k p . . p p p
  7 H P p . . . . .

  TEST CHECK------------------------

  Capital = black
  lower = white
  p = pawn
  q = queen
  k = king

    0 1 2 3 4 5 6 7
  0 . . . . . . . .
  1 . . . . . . . .
  2 . . . Q . . . .
  3 Q . . . . . . .
  4 . . . . Q . . .
  5 . . p p . . . . TEST 1 | TEST 2
  6 . . . k . . . .
  7 . . . . . . . .

    0 1 2 3 4 5 6 7
  0 . . . . . . . .
  1 . . . . . . . .
  2 . . . . . . . .
  3 . . . . . . . .
  4 . . . . . . . .
  5 . . . . . . . .
  6 . . . . . . . .
  7 . . . . . . . .


  */
